package com.tanhua.dubbo.server.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.dubbo.config.annotation.Service;
import com.tanhua.dubbo.server.pojo.Audio;
import com.tanhua.dubbo.server.service.IdService;
import com.tanhua.dubbo.server.vo.IdType;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.ArrayList;
import java.util.List;

@Service(version = "1.0.0")
@Slf4j
public class PeachBlossomAudioApiImpl implements PeachBlossomAudioApi {
    //音频数据存储在Redis中key的前缀
    private static final String AUDIO_REDIS_KEY_PREFIX = "AUDIO_COMMENT_";
    //系统推荐音频用户次数的前缀
    private static final String AUDIO_USER_COUNT_REDIS_KEY_PREFIX = "USER_AUDIO_COUNT_";
    //系统推荐用户音频id的前缀
    private static final String AUDIO_ID_USER_COUNT_REDIS_KEY_PREFIX = "USER_AUDIO_ID_";
    //用户重置桃花传音次数的时间
    private static final String AUDIO_COUNT_DATE_REDIS_KEY_PREFIX = "USER_AUDIO_DATE_";

    public static String getAudioRedisKeyPrefix() {
        return AUDIO_REDIS_KEY_PREFIX;
    }

    public static String getAudioIdUserCountRedisKeyPrefix(Long userId) {
        return AUDIO_ID_USER_COUNT_REDIS_KEY_PREFIX + userId;
    }

    public static String getAudioUserCountRedisKeyPrefix(Long userId) {
        return AUDIO_USER_COUNT_REDIS_KEY_PREFIX + userId;
    }

    public static String getAudioCountDateRedisKeyPrefix(Long userId) {
        return AUDIO_COUNT_DATE_REDIS_KEY_PREFIX + userId;
    }

    @Value("${user.audio.count}")
    private Integer counts;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private IdService idService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    /**
     * 实现功能:桃花传音中的上传音频的功能
     *
     * @param audio
     * @return
     */
    @Override
    public Boolean saveAudio(Audio audio) {
        try {
            audio.setId(ObjectId.get());
            audio.setAid(idService.creatIncrement(IdType.AUDIO));
            audio.setCreated(System.currentTimeMillis());
            Audio save = mongoTemplate.save(audio);
            if (ObjectUtil.isEmpty(save)) {
                log.error("音频没有保存成功!");
                return false;
            }
        } catch (Exception e) {
            log.error("保存音频异常!");
            return false;
        }
        return true;
    }


    /**
     * 实现功能:桃花传音中的接收音频的功能
     *
     * @return 返回音频信息
     */
    @Override
    public Audio receiveVoice(Long userId) {
        Audio audio = new Audio();
        String redisKey = getAudioRedisKeyPrefix();
        String redisKeyCount = getAudioUserCountRedisKeyPrefix(userId);
        String redisKeyAudioId = getAudioIdUserCountRedisKeyPrefix(userId);
        String countDateHash = getAudioCountDateRedisKeyPrefix(userId);
        //上次访问时间
        Object countDate = redisTemplate.opsForHash().get(redisKey, countDateHash);
        String today = DateUtil.today();
        //判断该用户是否第一次是记录接收语音
        if (ObjectUtil.isNotEmpty(countDate)) {
            if (Convert.toInt(countDate) != Convert.toInt(today)) {
                redisTemplate.opsForHash().put(redisKey, redisKeyCount, "10");
            }
        } else {
            redisTemplate.opsForHash().put(redisKey, redisKeyCount, "10");
        }
        Object object = redisTemplate.opsForHash().get(redisKey, redisKeyCount);
        Integer count = counts;
        //判断redis缓存中是否有该用户id接收语音的次数
        if (ObjectUtil.isNotEmpty(object)) {
            count = Convert.toInt(object);
        }
        //修改接收语音的时间
        redisTemplate.opsForHash().put(redisKey, countDateHash, today);
        //判断接收语音的次数是否已经用完了
        if (count == 0) {
            //TODO 接收语音次数已经用完了
            return null;
        } else {
            Object data = redisTemplate.opsForHash().get(redisKey, redisKeyAudioId);
            List<String> aIds = StrUtil.split(ObjectUtil.toString(data), ',');
            Query queryaId = Query.query(Criteria.where("aid").in(aIds)).with(Sort.by(Sort.Order.desc("created")));
            List<Audio> audioList = mongoTemplate.find(queryaId, Audio.class);
            //剩余次数
            count = count - 1;
            //推荐语音已经没有了
            if (CollUtil.isEmpty(audioList) || (counts - count) > audioList.size()) {
                if (CollUtil.isEmpty(audioList)) {
                    aIds = new ArrayList<>();
                }
                Query query = new Query().with(Sort.by(Sort.Order.desc("created"))).skip((counts - count) - aIds.size() - 1).limit(1);
                audio = mongoTemplate.findOne(query, Audio.class);
            } else {
                audio = audioList.get(counts - count - 1);
            }
            //存入redis缓存中
            audio.setCount(count);
            redisTemplate.opsForHash().put(redisKey, redisKeyCount, count + "");
        }

        return audio;
    }


}
